// models/SysDept.js
const mongoose = require("mongoose");
const { Schema } = mongoose;

/**
 * 系统部门表 - 对应 MySQL sys_dept 表
 * 使用树形结构存储部门层级关系
 */
const sysDeptSchema = new Schema(
  {
    // 部门ID - 对应MySQL的dept_id
    deptId: {
      type: Number,
      required: true,
      unique: true,
      index: true,
      comment: "部门id",
    },

    // 父部门ID - 对应MySQL的parent_id
    parentId: {
      type: Number,
      default: 0,
      index: true,
      comment: "父部门id",
    },

    // 祖级列表 - 对应MySQL的ancestors
    ancestors: {
      type: [Number], // 使用数组存储祖先ID列表
      default: [],
      comment: "祖级列表",
    },

    // 部门名称 - 对应MySQL的dept_name
    deptName: {
      type: String,
      required: [true, "部门名称不能为空"],
      trim: true,
      minlength: [1, "部门名称至少1个字符"],
      maxlength: [30, "部门名称不能超过30个字符"],
      comment: "部门名称",
    },

    // 显示顺序 - 对应MySQL的order_num
    orderNum: {
      type: Number,
      default: 0,
      min: [0, "显示顺序不能小于0"],
      comment: "显示顺序",
    },

    // 负责人 - 对应MySQL的leader
    leader: {
      type: String,
      default: null,
      maxlength: [20, "负责人姓名不能超过20个字符"],
      comment: "负责人",
    },

    // 联系电话 - 对应MySQL的phone
    phone: {
      type: String,
      default: null,
      match: [/^$|^1[3-9]\d{9}$/, "请输入有效的手机号码"],
      comment: "联系电话",
    },

    // 邮箱 - 对应MySQL的email
    email: {
      type: String,
      default: null,
      trim: true,
      lowercase: true,
      validate: {
        validator: function (email) {
          if (email === null || email === "") return true;
          return /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(email);
        },
        message: "请输入有效的邮箱地址",
      },
      comment: "邮箱",
    },

    // 部门状态 - 对应MySQL的status
    status: {
      type: String,
      enum: {
        values: ["0", "1"],
        message: "部门状态必须是 0(正常) 或 1(停用)",
      },
      default: "0",
      index: true,
      comment: "部门状态（0正常 1停用）",
    },

    // 删除标志 - 对应MySQL的del_flag
    delFlag: {
      type: String,
      enum: {
        values: ["0", "2"],
        message: "删除标志必须是 0(存在) 或 2(删除)",
      },
      default: "0",
      index: true,
      comment: "删除标志（0代表存在 2代表删除）",
    },

    // 创建者 - 对应MySQL的create_by
    createBy: {
      type: String,
      default: "",
      comment: "创建者",
    },

    // 创建时间 - 对应MySQL的create_time
    createTime: {
      type: Date,
      default: Date.now,
      comment: "创建时间",
    },

    // 更新者 - 对应MySQL的update_by
    updateBy: {
      type: String,
      default: "",
      comment: "更新者",
    },

    // 更新时间 - 对应MySQL的update_time
    updateTime: {
      type: Date,
      default: Date.now,
      comment: "更新时间",
    },
  },
  {
    // Schema 选项
    timestamps: false,
    collection: "sys_depts",
    toJSON: { virtuals: true },
    toObject: { virtuals: true },
  }
);

// 创建复合索引
sysDeptSchema.index({ parentId: 1, orderNum: 1 });
sysDeptSchema.index({ delFlag: 1, status: 1 });
sysDeptSchema.index({ ancestors: 1 });
sysDeptSchema.index({ deptName: 1 });

// 虚拟字段
sysDeptSchema.virtual("isActive").get(function () {
  return this.status === "0" && this.delFlag === "0";
});

sysDeptSchema.virtual("isRoot").get(function () {
  return this.parentId === 0;
});

sysDeptSchema.virtual("statusText").get(function () {
  const statusMap = { 0: "正常", 1: "停用" };
  return statusMap[this.status] || "未知";
});

sysDeptSchema.virtual("ancestorNames").get(function () {
  // 这个虚拟字段需要在查询时通过 populate 填充
  return this._ancestorNames || [];
});

// 子部门虚拟字段
sysDeptSchema.virtual("children", {
  ref: "SysDept",
  localField: "deptId",
  foreignField: "parentId",
  justOne: false,
});

// 父部门虚拟字段
sysDeptSchema.virtual("parent", {
  ref: "SysDept",
  localField: "parentId",
  foreignField: "deptId",
  justOne: true,
});

// 实例方法
sysDeptSchema.methods = {
  // 获取部门完整路径
  getFullPath: function (separator = " / ") {
    if (this.ancestorNames && this.ancestorNames.length > 0) {
      return this.ancestorNames.join(separator) + separator + this.deptName;
    }
    return this.deptName;
  },

  // 启用/禁用部门
  toggleStatus: function () {
    this.status = this.status === "0" ? "1" : "0";
    this.updateTime = new Date();
    return this.save();
  },

  // 软删除部门
  softDelete: function () {
    this.delFlag = "2";
    this.updateTime = new Date();
    return this.save();
  },

  // 恢复部门
  restore: function () {
    this.delFlag = "0";
    this.updateTime = new Date();
    return this.save();
  },

  // 更新祖先列表（当父部门改变时调用）
  updateAncestors: async function () {
    if (this.parentId === 0) {
      this.ancestors = [];
    } else {
      const parentDept = await mongoose.model("SysDept").findOne({
        deptId: this.parentId,
        delFlag: "0",
      });

      if (parentDept) {
        this.ancestors = [...parentDept.ancestors, parentDept.deptId];
      } else {
        this.ancestors = [];
      }
    }

    this.updateTime = new Date();
    await this.save();

    // 递归更新所有子部门的祖先列表
    await this.updateChildrenAncestors();

    return this;
  },

  // 更新所有子部门的祖先列表
  updateChildrenAncestors: async function () {
    const children = await mongoose.model("SysDept").find({
      parentId: this.deptId,
      delFlag: "0",
    });

    for (const child of children) {
      child.ancestors = [...this.ancestors, this.deptId];
      child.updateTime = new Date();
      await child.save();
      await child.updateChildrenAncestors();
    }
  },

  // 检查是否是指定部门的子部门
  isDescendantOf: function (deptId) {
    return this.ancestors.includes(deptId);
  },

  // 检查是否是指定部门的父部门
  isAncestorOf: async function (deptId) {
    const targetDept = await mongoose.model("SysDept").findOne({
      deptId: deptId,
      delFlag: "0",
    });

    return targetDept ? targetDept.ancestors.includes(this.deptId) : false;
  },

  // 获取所有子部门ID（包括间接子部门）
  getAllDescendantIds: async function () {
    const descendants = await mongoose.model("SysDept").find({
      ancestors: this.deptId,
      delFlag: "0",
    });

    return descendants.map((dept) => dept.deptId);
  },

  // 获取直接子部门数量
  getChildrenCount: async function () {
    return await mongoose.model("SysDept").countDocuments({
      parentId: this.deptId,
      delFlag: "0",
      status: "0",
    });
  },
};

// 静态方法
sysDeptSchema.statics = {
  // 根据部门ID查找部门
  findByDeptId: function (deptId) {
    return this.findOne({
      deptId: deptId,
      delFlag: "0",
    });
  },

  // 根据部门名称查找部门
  findByDeptName: function (deptName) {
    return this.findOne({
      deptName: new RegExp(`^${deptName}$`, "i"),
      delFlag: "0",
    });
  },

  // 获取根部门（parentId = 0）
  findRootDepts: function () {
    return this.find({
      parentId: 0,
      delFlag: "0",
    }).sort({ orderNum: 1 });
  },

  // 获取所有有效部门（树形结构）
  findDeptTree: async function (options = {}) {
    const { includeDisabled = false, includeDeleted = false } = options;

    const query = {};
    if (!includeDeleted) {
      query.delFlag = "0";
    }
    if (!includeDisabled) {
      query.status = "0";
    }

    const depts = await this.find(query).sort({ parentId: 1, orderNum: 1 });

    return this.buildDeptTree(depts);
  },

  // 构建部门树形结构
  buildDeptTree: function (depts, parentId = 0) {
    const tree = [];

    for (const dept of depts) {
      if (dept.parentId === parentId) {
        const children = this.buildDeptTree(depts, dept.deptId);
        if (children.length > 0) {
          dept._doc.children = children;
        }
        tree.push(dept);
      }
    }

    return tree;
  },

  // 根据父部门ID获取子部门
  findChildrenByParentId: function (parentId, options = {}) {
    const { includeDisabled = false } = options;

    const query = {
      parentId: parentId,
      delFlag: "0",
    };

    if (!includeDisabled) {
      query.status = "0";
    }

    return this.find(query).sort({ orderNum: 1 });
  },

  // 获取部门路径（从根部门到当前部门）
  getDeptPath: async function (deptId) {
    const dept = await this.findOne({
      deptId: deptId,
      delFlag: "0",
    });

    if (!dept) {
      return [];
    }

    const path = [];

    // 添加祖先部门
    if (dept.ancestors.length > 0) {
      const ancestors = await this.find({
        deptId: { $in: dept.ancestors },
        delFlag: "0",
      }).sort({ deptId: 1 });

      path.push(...ancestors);
    }

    // 添加当前部门
    path.push(dept);

    return path;
  },

  // 分页查询部门
  findDeptsPaginated: function (options = {}) {
    const {
      page = 1,
      limit = 10,
      deptName = "",
      status = "",
      parentId = null,
    } = options;

    const skip = (page - 1) * limit;
    const query = { delFlag: "0" };

    // 构建查询条件
    if (deptName) {
      query.deptName = { $regex: deptName, $options: "i" };
    }

    if (status) {
      query.status = status;
    }

    if (parentId !== null && parentId !== undefined) {
      query.parentId = parentId;
    }

    return Promise.all([
      this.find(query)
        .skip(skip)
        .limit(limit)
        .sort({ parentId: 1, orderNum: 1 }),
      this.countDocuments(query),
    ]).then(([depts, total]) => ({
      depts,
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        pages: Math.ceil(total / limit),
      },
    }));
  },

  // 部门统计
  getDeptStats: function () {
    return this.aggregate([
      {
        $match: { delFlag: "0" },
      },
      {
        $group: {
          _id: "$status",
          count: { $sum: 1 },
          avgOrderNum: { $avg: "$orderNum" },
        },
      },
      {
        $project: {
          status: "$_id",
          count: 1,
          avgOrderNum: { $round: ["$avgOrderNum", 2] },
          _id: 0,
        },
      },
    ]);
  },

  // 检查部门名称是否已存在
  isDeptNameExists: function (deptName, parentId, excludeDeptId = null) {
    const query = {
      deptName: new RegExp(`^${deptName}$`, "i"),
      parentId: parentId,
      delFlag: "0",
    };

    if (excludeDeptId) {
      query.deptId = { $ne: excludeDeptId };
    }

    return this.findOne(query);
  },

  // 获取部门的所有父部门
  getParentDepts: async function (deptId) {
    const dept = await this.findOne({
      deptId: deptId,
      delFlag: "0",
    });

    if (!dept || dept.ancestors.length === 0) {
      return [];
    }

    return this.find({
      deptId: { $in: dept.ancestors },
      delFlag: "0",
    }).sort({ deptId: 1 });
  },
};

// 查询助手
sysDeptSchema.query = {
  // 按状态筛选
  byStatus: function (status) {
    return this.where("status").equals(status);
  },

  // 按父部门筛选
  byParentId: function (parentId) {
    return this.where("parentId").equals(parentId);
  },

  // 按删除状态筛选
  byDelFlag: function (delFlag = "0") {
    return this.where("delFlag").equals(delFlag);
  },

  // 搜索部门名称
  searchByName: function (keyword) {
    return this.where({
      deptName: { $regex: keyword, $options: "i" },
    });
  },

  // 按显示顺序排序
  sortByOrder: function (direction = "asc") {
    const sortOrder = direction === "desc" ? -1 : 1;
    return this.sort({ orderNum: sortOrder });
  },
};

// 中间件
sysDeptSchema.pre("save", async function (next) {
  // 更新更新时间
  this.updateTime = new Date();

  // 自动生成祖先列表（如果是新部门）
  if (this.isNew && this.parentId !== 0) {
    const parentDept = await this.constructor.findOne({
      deptId: this.parentId,
      delFlag: "0",
    });

    if (parentDept) {
      this.ancestors = [...parentDept.ancestors, parentDept.deptId];
    } else {
      this.ancestors = [];
    }
  }

  // 邮箱转小写
  if (this.isModified("email") && this.email) {
    this.email = this.email.toLowerCase();
  }

  next();
});

// 删除前的中间件（软删除所有子部门）
sysDeptSchema.pre("save", async function (next) {
  if (this.isModified("delFlag") && this.delFlag === "2") {
    // 软删除所有子部门
    await this.constructor.updateMany(
      { ancestors: this.deptId, delFlag: "0" },
      {
        delFlag: "2",
        updateTime: new Date(),
        updateBy: this.updateBy || "",
      }
    );
  }
  next();
});

// 创建模型
const SysDept = mongoose.model("SysDept", sysDeptSchema);

module.exports = SysDept;